package com.pajk.user.jmeter;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Random;

import org.apache.jmeter.config.Arguments;
import org.apache.jmeter.protocol.java.sampler.AbstractJavaSamplerClient;
import org.apache.jmeter.protocol.java.sampler.JavaSamplerContext;
import org.apache.jmeter.samplers.SampleResult;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.pajk.user.api.UserService;

public class UserService_updateMobile extends AbstractJavaSamplerClient {

	private String jMeterPrefix = null;
	private String jMeterOutput = null;
	private int jMeterRepeat = 0;

	private ClassPathXmlApplicationContext appContext = null;

	private UserService userService = null;

	private String[] userIds = null;
	private Map<Long, Long> userIdMobileMap = null;

	private BufferedWriter bw = null;

	public static void main(String[] args) {

		Thread.currentThread().setName("Thread Group 1-1");
		JavaSamplerContext context = new JavaSamplerContext(new Arguments());
		UserService_updateMobile test = new UserService_updateMobile();
		test.setupTest(context);
		test.runTest(context);
		test.teardownTest(context);
	}

	public Arguments getDefaultParameters() {

		Arguments params = new Arguments();

		params.addArgument(Utility.JMETER_PREFIX_LABEL,
				Utility.JMETER_PREFIX_DEFAULT);
		params.addArgument(Utility.JMETER_OUTPUT_LABEL,
				Utility.JMETER_OUTPUT_DEFAULT);
		params.addArgument(Utility.JMETER_REPEAT_LABEL, new Integer(
				Utility.JMETER_REPEAT_DEFAULT).toString());

		return params;
	}

	public void setupTest(JavaSamplerContext context) {

		super.setupTest(context);

		jMeterPrefix = context.getParameter(Utility.JMETER_PREFIX_LABEL,
				Utility.JMETER_PREFIX_DEFAULT);
		jMeterOutput = context.getParameter(Utility.JMETER_OUTPUT_LABEL,
				Utility.JMETER_OUTPUT_DEFAULT);
		jMeterRepeat = context.getIntParameter(Utility.JMETER_REPEAT_LABEL,
				Utility.JMETER_REPEAT_DEFAULT);

		appContext = new ClassPathXmlApplicationContext(
				Utility.USER_SERVICE_REFERENCE_DEFINITION);
		appContext.start();

		userService = (UserService) appContext.getBean("userService");

		String name = Thread.currentThread().getName();
		int groupId = Utility.parseGroupId(name);
		int threadId = Utility.parseThreadId(name);

		try {
			userIds = Utility.populateUserIdsCacheFromLog(jMeterPrefix,
					jMeterOutput, jMeterRepeat, groupId, threadId);
		} catch (FileNotFoundException e) {
			this.getLogger().error(e.getMessage(), e.getCause());
		} catch (IOException e) {
			this.getLogger().error(e.getMessage(), e.getCause());
		}

		userIdMobileMap = new HashMap<Long, Long>();

		StringBuffer sb = new StringBuffer();
		sb.append(jMeterOutput);
		sb.append(jMeterPrefix);
		sb.append('-');
		sb.append(name);
		sb.append('-');
		sb.append(Utility.MOBILES);
		sb.append(Utility.LOGEXT);

		String results = sb.toString();

		File dirs = new File(jMeterOutput);
		if (!dirs.exists()) {
			dirs.mkdirs();
		}

		try {
			bw = new BufferedWriter(new FileWriter(results, false));
		} catch (IOException e) {
			this.getLogger().error(e.getMessage(), e.getCause());
		}
	}

	@Override
	public SampleResult runTest(JavaSamplerContext arg0) {

		SampleResult sampleResult = new SampleResult();

		int count = new Random().nextInt(jMeterRepeat);
		long userId = Long.parseLong(userIds[count]);
		long mobile = new Random().nextLong();

		try {
			sampleResult.sampleStart();

			userService.updateMobile(userId, mobile);

			sampleResult.setSuccessful(true);
		} catch (Exception e) {
			sampleResult.setSuccessful(false);
			this.getLogger().error(e.getMessage(), e.getCause());
		} finally {
			if (sampleResult != null) {
				sampleResult.sampleEnd();
				if (sampleResult.isSuccessful()) {
					userIdMobileMap.put(userId, mobile);
				}
			}
		}

		return sampleResult;
	}

	public void teardownTest(JavaSamplerContext context) {

		super.teardownTest(context);

		try {
			int size = userIdMobileMap.size();
			bw.write("size: " + size + "\r");
			Iterator<Long> iter = (Iterator<Long>) userIdMobileMap.keySet()
					.iterator();
			while (iter.hasNext()) {
				long mobile = (Long) userIdMobileMap.get(iter.next());
				bw.write(new Long(mobile).toString());
				bw.write("\r");
			}
			bw.flush();
		} catch (IOException e) {
			this.getLogger().error(e.getMessage(), e.getCause());
		}

		appContext.close();
	}

}